ident = '$Id: script_helper.py 109 2006-06-05 18:46:37Z trevor $'

import sys, os, wx, wx.html, common, re, icon_manager, time
import wx.stc as stc

class dialog( wx.Dialog ):
	def __init__( self, parent ):
		wx.Dialog.__init__( self, parent, -1, "Script Helper", wx.DefaultPosition,
							wx.Size( 800, 600 ), style=wx.RESIZE_BORDER | wx.DEFAULT_DIALOG_STYLE )
		common.metalic(self)
		icon = icon_manager.get_icon( 'ESM' )
		self.SetIcon( icon )
		self.doc = {}
		self.tSplitter	= wx.SplitterWindow( self, -1, style = wx.SP_LIVE_UPDATE )
		self.dSplitter	= wx.SplitterWindow( self.tSplitter, -1, style = wx.SP_LIVE_UPDATE )
		# create the tree ctrl
		style = wx.TR_HAS_BUTTONS | wx.TR_NO_LINES | wx.TR_HIDE_ROOT
		if wx.Platform == '__WXMSW__':
			style = wx.TR_HAS_BUTTONS  | wx.TR_LINES_AT_ROOT | wx.TR_HIDE_ROOT
		self.tree = wx.TreeCtrl( self.tSplitter, -1, style=style )
		self.tree.Bind( wx.EVT_TREE_SEL_CHANGED, self.OnItemSelected, id=self.tree.GetId() )
		if wx.Platform == '__WXMAC__':
			font = self.tree.GetFont()
			font.SetPointSize( 10 )
			self.tree.SetFont( font )
		# the html window
		self.html = wx.html.HtmlWindow( self.dSplitter, -1 ) # style=wx.NO_FULL_REPAINT_ON_RESIZE )
		self.code = stc.StyledTextCtrl( self.dSplitter, -1 )
		self.code.SetStyleBits( 7 )
		self.code.StyleSetSpec( stc.STC_STYLE_DEFAULT, "size:%s,face:%s" % (common.default_font_size, common.default_font_family ))
		self.code.SetEOLMode( stc.STC_EOL_LF )
		self.code.SetLexer( stc.STC_LEX_HTML )
		self.code.SetStyleBits( 7 )
		self.code.SetMargins( 0, 0 )
		#self.code.SetMarginType( 2, stc.STC_MARGIN_NUMBER )
		#self.code.SetMarginSensitive( 2, True )
		self.code.SetMarginWidth( 0, 0 )
		self.code.SetMarginWidth( 1, 0 )
		self.code.SetMarginWidth( 2, 0 )
		self.code.SetBufferedDraw( 1 )
		self.code.SetEdgeMode( stc.STC_EDGE_LINE )
		self.code.SetEdgeColumn( 80 )
		self.code.SetTabWidth( 4 )
		self.code.SetUseTabs( True )
		self.code.SetTabIndents( 4 )
		self.code.SetIndent( 4 )
		self.code.SetIndentationGuides( True )
		self.code.SetCaretPeriod( 100 )
		self.code.SetCaretWidth( 4 )
		self.code.SetCaretForeground( "#FF0000" )
		self.code.StyleSetSpec( stc.STC_STYLE_LINENUMBER, "back:%s" % common.sui_colors("gray80") )
		self.code.StyleSetSpec( stc.STC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF, bold" )
		self.code.StyleSetSpec( stc.STC_STYLE_BRACEBAD  , "fore:#FFFFFF,back:#FF0000, bold" )
		# normal html
		self.code.StyleSetSpec( stc.STC_H_DEFAULT, "fore:%s" % common.sui_colors("darkslategray") )
		self.code.StyleSetSpec( stc.STC_H_TAG, "fore:#4433CC,bold" )
		self.code.StyleSetSpec( stc.STC_H_TAGUNKNOWN, "fore:#CC0055,back:%s,bold" % common.sui_colors("cornsilk") )
		self.code.StyleSetSpec( stc.STC_H_ATTRIBUTE, "fore:#336655" ) # #336655
		self.code.StyleSetSpec( stc.STC_H_ATTRIBUTEUNKNOWN, "fore:%s,back:%s" % ( common.sui_colors("indianred"), common.sui_colors("cornsilk") ) ) #fore:#555588
		self.code.StyleSetSpec( stc.STC_H_DOUBLESTRING, "fore:#888822" )
		self.code.StyleSetSpec( stc.STC_H_NUMBER, "fore:#992299" )
		self.code.StyleSetSpec( stc.STC_H_COMMENT, "fore:#11AA33,back:#EEFFEE" )
		# javascript
		self.code.StyleSetSpec( stc.STC_HJ_DEFAULT, "back:#ffefef,fore:%s,eol" % common.sui_colors("mediumslateblue") )
		self.code.StyleSetSpec( stc.STC_HJ_SYMBOLS, "back:#ffefef,fore:%s,bold" % common.sui_colors("indianred") )
		self.code.StyleSetSpec( stc.STC_HJ_WORD, "back:#ffefef,fore:#4433CC,bold" )
		self.code.StyleSetSpec( stc.STC_HJ_REGEX, "fore:#CC0055,back:%s,bold" % common.sui_colors("cornsilk") )
		self.code.StyleSetSpec( stc.STC_HJ_SINGLESTRING, "back:#ffefef,fore:#336655" ) # #336655
		self.code.StyleSetSpec( stc.STC_HJ_KEYWORD, "fore:%s,back:%s,bold" % ( common.sui_colors("indianred"), common.sui_colors("cornsilk") ) ) #fore:#555588
		self.code.StyleSetSpec( stc.STC_HJ_DOUBLESTRING, "back:#ffefef,fore:#888822" )
		self.code.StyleSetSpec( stc.STC_HJ_NUMBER, "back:#ffefef,fore:#992299" )
		self.code.StyleSetSpec( stc.STC_HJ_COMMENT, "fore:#11aa44,back:#ffefef,eol" )
		self.code.StyleSetSpec( stc.STC_HJ_COMMENTLINE, "fore:#11aa44,back:#ffefef,eol" )
		self.code.StyleSetSpec( stc.STC_HJ_COMMENTDOC, "fore:#11aa44,back:#ffefef,eol" )

		self.tSplitter.SplitVertically( self.tree, self.dSplitter, 150 )
		self.dSplitter.SplitHorizontally( self.html, self.code )

		# Add the buttons
		self.button_sizer = wx.BoxSizer( wx.HORIZONTAL )
		btn = wx.Button( self, -1, "&Update" )
		btn.Bind( wx.EVT_BUTTON, self.OnUpdate )
		#self.button_sizer.Add( (0,0) , 0, 1 )
		self.button_sizer.Add( btn, 0, 0 )
		self.button_sizer.Add( (10,10), 1, 1 )
		btn = wx.Button( self, wx.ID_OK, "&Insert" )
		btn.SetDefault()
		self.button_sizer.Add( btn, 0, 0 )
		btn = wx.Button( self, wx.ID_CANCEL, "&Cancel" )
		self.button_sizer.Add( btn, 0, 0 )

		self.sizer = wx.BoxSizer( wx.VERTICAL )
		self.sizer.Add( self.tSplitter, 1, wx.EXPAND | wx.NORTH | wx.SOUTH | wx.EAST | wx.WEST, 10 )
		self.sizer.Add( self.button_sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.SOUTH, 10 )

		self.SetSizer( self.sizer )
		self.SetAutoLayout( 1 )
		self.Layout()
		self.html.SetPage("<html><body><h1>Script Helper</h1>Select a script to insert</body></html>")
		self.load_script()

	def load_script( self ):
		doc = self.get_doc()
		if not doc: return
		#common.dprint( "Got Doc --[%s]--" % doc )
		self.tree.DeleteAllItems()
		self.root = self.tree.AddRoot( "script" )
		# parse the doc
		catpat = re.compile( "<category\s+label\s*=\s*\"([^\"]+)\"\s+created_on\s*=\s*\"([^\"]+)\"\s+updated_on\s*=\s*\"([^\"]+)\"\s*>\s*(<description>(.*)</description>)\s*(<code>(.*)</code>)(.*)</category>", re.U | re.S | re.M )
		subpat = re.compile( "<sub_category\s+label\s*=\s*\"([^\"]+)\"\s+created_on\s*=\s*\"([^\"]+)\"\s+updated_on\s*=\s*\"([^\"]+)\"\s*>\s*(<sub_description>(.*)</sub_description>)\s*(<sub_code>(.*)</sub_code>)\s*</sub_category>", re.U | re.S | re.M )
		cats = re.split( "</category>", doc )
		for cat in cats:
			# get the cat info
			cat = cat.strip() + '</category>'
			m = catpat.match( cat )
			if m and m.groups():
				g = m.groups()
				cat_name = g[0].strip()
				cat_co   = g[1].strip()
				cat_uo   = g[2].strip()
				cat_desc = g[4].strip()
				cat_code = g[6].strip()
				cat_subs = g[7].strip()
				cat_item = self.tree.AppendItem( self.root, cat_name )
				#common.dprint('cat_item', cat_item)
				self.tree.SetPyData( cat_item, {'name':cat_name, 'created_on':cat_co,'updated_on':cat_uo,'description':cat_desc,'code':cat_code} )
				subs = re.split( "</sub_category>", cat_subs )
				for sub in subs:
					# get the cat info
					sub = sub.strip() + '</sub_category>'
					m = subpat.match( sub )
					if m and m.groups():
						g = m.groups()
						sub_name = g[0].strip()
						sub_co   = g[1].strip()
						sub_uo   = g[2].strip()
						sub_desc = g[4].strip()
						sub_code = g[6].strip()
						sub_item = self.tree.AppendItem( cat_item, sub_name )
						#common.dprint('sub_item', sub_item)
						self.tree.SetPyData( sub_item, {'name':sub_name, 'created_on':sub_co,'updated_on':sub_uo,'description':sub_desc,'code':sub_code} )
	def get_doc( self ):
		if not os.path.isfile( common.doc_filename ):
			if not self.download_update():
				return None
		f = file( common.doc_filename, 'r' )
		doc = f.read()
		f.close()
		return doc

	def download_update( self ):
		busy = wx.BusyInfo("One moment please, downloading update...")
		wx.Yield()
		time.sleep(1)
		#vars = [( u'cid', u'8bc7682159341a6d007192fe52ab95a1' ),
		#		( u'iid', u'5413' ),
		#		( u'rtalk', u'71' ),]
		result = False
		doc = ''
		try:
			form= common.http_post_form( 'www.etelos.com', '/scripthelper/index.esp', () )
			common.dprint("Sending request");
			doc	= form.submit()
			common.dprint("Got result: %s" % doc);
			doc = doc.strip()
			if len( doc ) < 50:
				common.dprint( "Download failed: ", doc )
			else:
				result = True
		except:
			common.show_error("Failed to download documentation update")
		del busy
		# save to file
		if result:
			f = file( common.doc_filename, 'w' )
			f.write( doc )
			f.close()
		return result

	def OnItemSelected( self, event ):
		#common.dprint( dir( event ) )
		item = None
		try:
			titem = event.GetItem()
			#common.dprint( "got item", titem )
			item = self.tree.GetPyData( titem )
		except:
			pass
		if not item: return
		self.html.SetPage( item['description'] )
		self.code.SetText( item['code'] )

	def OnUpdate( self, event ):
		self.download_update()
		self.load_script()